package org.jetnuke.modules.download;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.jetnuke.common.ActionForward;
import org.jetnuke.common.IAction;
import org.jetnuke.common.IAdminInfo;
import org.jetnuke.common.IModuleInfo;
import org.jetnuke.common.IUserInfo;
import org.jetnuke.dao.DataAccessDriver;
import org.jetnuke.dao.DownloadDownloadDAO;
import org.jetnuke.entities.DownloadsDownloads;
import org.jetnuke.entities.DownloadsVoteData;
import org.jetnuke.util.JetUtil;

public class Rate implements IAction {
	int id;

	String rating;

	String comment="";

	/**
	 * @param comment
	 *            The comment to set.
	 */
	public void setComment(String comment) {
		this.comment = comment;
	}

	/**
	 * @param id
	 *            The id to set.
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @param rating
	 *            The rating to set.
	 */
	public void setRating(String rating) {
		this.rating = rating;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.jetnuke.common.IAction#exec(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse,
	 *      org.apache.velocity.VelocityContext, org.jetnuke.common.IModuleInfo,
	 *      java.lang.String, org.jetnuke.common.IUserInfo,
	 *      org.jetnuke.common.IAdminInfo)
	 */
	public ActionForward exec(HttpServletRequest request,
			HttpServletResponse response, VelocityContext vc, IModuleInfo info,
			String op, IUserInfo ui, IAdminInfo ai) throws Exception {

		String ip = request.getRemoteAddr();
		boolean pass = true;
		int error = -1;

		if (rating.equals("--")) {
			pass = false;
			error = 0;
		}

		if (pass && ui != null) {
			String uname = ui.getUname();
			int count=DataAccessDriver.getInst().newDownloadDownloadDAO().countUser(id,uname);
			//List ls = downloads_downloadsPeer.doSelect(new Criteria().add(
				//	downloads_downloadsPeer.LID, id).add(
					//downloads_downloadsPeer.SUBMITTER, uname));

			//if (!ls.isEmpty()) {//own link
			if(count>0){
				pass = false;
				error = 1;
			}
			count=DataAccessDriver.getInst().newDownloadVoteDAO().countUser(id,uname);
			//ls = downloads_votedataPeer.doSelect(new Criteria().add(
			//		downloads_votedataPeer.RATINGLID, id).add(
			//		downloads_votedataPeer.RATINGUSER, uname));
			//if (!ls.isEmpty()) {//already voted
			if(count>0){
				pass = false;
				error = 2;
			}

		} else {//anonymous

			GregorianCalendar gc = new GregorianCalendar();
			gc.add(Calendar.DATE, -1);
			
			int count=DataAccessDriver.getInst().newDownloadVoteDAO().countAnonymous(id,ip,gc.getTime());
			if(count>0){
			/*List ls = downloads_votedataPeer.doSelect(new Criteria().add(
					downloads_votedataPeer.RATINGLID, id).add(
					downloads_votedataPeer.RATINGUSER, "").add(
					downloads_votedataPeer.RATINGHOSTNAME, ip).add(
					downloads_votedataPeer.RATINGTIMESTAMP, gc.getTime(),
					Criteria.GREATER_EQUAL));*/
			//if (!ls.isEmpty()) {//already voted
				pass = false;
				error = 3;
			}
		}
		if (pass) {
			int iRating = Integer.parseInt(rating);
			DownloadsVoteData dt=new DownloadsVoteData();
			//downloads_votedata dt = new downloads_votedata();
			dt.setRATINGLID(id);
			dt.setRATINGTIMESTAMP(new Date());
			dt.setRATING(iRating);
			if (ui != null)
				dt.setRATINGUSER(ui.getUname());
			else
				dt.setRATINGUSER("");
			dt.setRATINGCOMMENTS(comment.trim());
			dt.setRATINGHOSTNAME(request.getRemoteAddr());
			DataAccessDriver.getInst().newDownloadVoteDAO().addNew(dt);
			//dt.save();

			
			double rate=calcRate(id,10);//TODO
			DownloadDownloadDAO ddm=DataAccessDriver.getInst().newDownloadDownloadDAO();
			DownloadsDownloads dd=DataAccessDriver.getInst().newDownloadDownloadDAO().retrieveByPK(id); 			
			//downloads_downloads dd = downloads_downloadsPeer.retrieveByPK(id);
			dd.setTOTALVOTES(dd.getTOTALVOTES()+1);
			if ( comment.trim().length() > 0)
				dd.setTOTALCOMMENTS(dd.getTOTALCOMMENTS() + 1);
			dd.setDOWNLOADRATINGSUMMARY(rate);
			ddm.update(dd);
			//dd.save();
			JetUtil.redirect(vc,response,request.getContextPath()+"/do/download/votevalid");
			//PHPNuke has a much more sophisticated way to calculate the
			// rating.
		} else {
			JetUtil.redirect(vc,response,request.getContextPath()+"/do/download/novalid?error="
					+ String.valueOf(error));
		}

		return null;
	}
	private double calcRate(int lid,int impact)throws Exception{
		double finalRating=0;
		List ls=DataAccessDriver.getInst().newDownloadVoteDAO().getByRatingLid(lid);
		//List ls=downloads_votedataPeer.doSelect(new Criteria().add(downloads_votedataPeer.RATINGLID,lid));
		int totalVotes=ls.size();
		Iterator it=ls.iterator();
		int anonvotes = 0;
		
		int anonvoteval = 0;
		int regvoteval = 0;
		while(it.hasNext()){
			DownloadsVoteData vote=(DownloadsVoteData)it.next();
			int ratingVote=vote.getRATING();
			String user=vote.getRATINGUSER();
			if(user==null || user.length()==0){
				anonvotes++;
				anonvoteval += ratingVote;
			}else{
				regvoteval += ratingVote;
			}
		}
		int regvotes = totalVotes - anonvotes;
		if(totalVotes>0){
			if(regvotes==0){//Only anon
				finalRating = anonvoteval*1. / anonvotes;
			}
			else if (anonvotes==0){ //Only reg
				finalRating = regvoteval*1. / regvotes;	
			}else{
				 double avgRU = regvoteval *1./ regvotes;
				 double avgAU = anonvoteval *1./ anonvotes;
				 double impactRU = regvotes;
				 double impactAU = anonvotes *1./ impact;
				 finalRating = ((avgRU * impactRU) + (avgAU * impactAU) ) / (impactRU + impactAU);
			}
		}
		return finalRating;
	}

}
